{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "SMFUgtvbFeLQ"
   },
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/docs/gen-qa-openai.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/docs/gen-qa-openai.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "v0to-QXCQjsm"
   },
   "source": [
    "# Question Answering using Retrieval Augmented Generation and Cascading Retrieval\n",
    "\n",
    "## Intro\n",
    "\n",
    "In this notebook we will learn how to query relevant contexts to our queries from Pinecone, and pass these to a generative OpenAI model to generate an answer backed by real data sources. Specifically, we'll answer questions about a subset of research papers on AI from Arxiv.\n",
    "\n",
    "To do so, we'll implement [cascading retrieval](https://www.pinecone.io/blog/cascading-retrieval/), a search pattern using Pinecone that involves creating sparse and dense indexes, searching a single query across both, then reranking the results to find the most relevant set of information for our query.\n",
    "\n",
    "Then, we'll hook up a prompt to an OpenAI LLM call to generate our answer. \n",
    "\n",
    "Let's begin by installing our requisite packages and getting our data ready:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "VpMvHAYRQf9N",
    "outputId": "42705370-c5bf-417b-fe8a-3f6d0fe28fbb"
   },
   "outputs": [],
   "source": [
    "!pip install -qU \\\n",
    "    openai==1.86.0 \\\n",
    "    pinecone==7.0.2 \\\n",
    "    datasets==3.6.0 \\\n",
    "    backoff==2.2.1 \\\n",
    "    pinecone-notebooks==0.1.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "NhWnLkHqmeWI"
   },
   "source": [
    "---\n",
    "### Demo Data: Arxiv Papers\n",
    "\n",
    "In this example, we'll show you how to build a simple RAG workflow over a set of Arxiv paper abstracts.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'id': '2401.04088',\n",
       " 'title': 'Mixtral of Experts',\n",
       " 'summary': 'We introduce Mixtral 8x7B, a Sparse Mixture of Experts (SMoE) language model.\\nMixtral has the same architecture as Mistral 7B, with the difference that each\\nlayer is composed of 8 feedforward blocks (i.e. experts). For every token, at\\neach layer, a router network selects two experts to process the current state\\nand combine their outputs. Even though each token only sees two experts, the\\nselected experts can be different at each timestep. As a result, each token has\\naccess to 47B parameters, but only uses 13B active parameters during inference.\\nMixtral was trained with a context size of 32k tokens and it outperforms or\\nmatches Llama 2 70B and GPT-3.5 across all evaluated benchmarks. In particular,\\nMixtral vastly outperforms Llama 2 70B on mathematics, code generation, and\\nmultilingual benchmarks. We also provide a model fine-tuned to follow\\ninstructions, Mixtral 8x7B - Instruct, that surpasses GPT-3.5 Turbo,\\nClaude-2.1, Gemini Pro, and Llama 2 70B - chat model on human benchmarks. Both\\nthe base and instruct models are released under the Apache 2.0 license.',\n",
       " 'source': 'http://arxiv.org/pdf/2401.04088',\n",
       " 'authors': 'Albert Q. Jiang, Alexandre Sablayrolles, Antoine Roux, Arthur Mensch, Blanche Savary, Chris Bamford, Devendra Singh Chaplot, Diego de las Casas, Emma Bou Hanna, Florian Bressand, Gianna Lengyel, Guillaume Bour, Guillaume Lample, Lélio Renard Lavaud, Lucile Saulnier, Marie-Anne Lachaux, Pierre Stock, Sandeep Subramanian, Sophia Yang, Szymon Antoniak, Teven Le Scao, Théophile Gervet, Thibaut Lavril, Thomas Wang, Timothée Lacroix, William El Sayed',\n",
       " 'categories': 'cs.LG, cs.CL',\n",
       " 'comment': 'See more details at https://mistral.ai/news/mixtral-of-experts/',\n",
       " 'journal_ref': None,\n",
       " 'primary_category': 'cs.LG',\n",
       " 'published': '20240108',\n",
       " 'updated': '20240108',\n",
       " 'content': \"4 2 0 2\\nn a J 8 ] G L . s c [\\n1 v 8 8 0 4 0 . 1 0 4 2 : v i X r a\\n# Mixtral of Experts\\nAlbert Q. Jiang, Alexandre Sablayrolles, Antoine Roux, Arthur Mensch, Blanche Savary, Chris Bamford, Devendra Singh Chaplot, Diego de las Casas, Emma Bou Hanna, Florian Bressand, Gianna Lengyel, Guillaume Bour, Guillaume Lample, LÃ©lio Renard Lavaud, Lucile Saulnier, Marie-Anne Lachaux, Pierre Stock, Sandeep Subramanian, Sophia Yang, Szymon Antoniak, Teven Le Scao, ThÃ©ophile Gervet, Thibaut Lavril, Thomas Wang, TimothÃ©e Lacroix, William El Sayed\\n\\nAbstract\\nWe introduce Mixtral 8x7B, a Sparse Mixture of Experts (SMoE) language model. Mixtral has the same architecture as Mistral 7B, with the difference that each layer is composed of 8 feedforward blocks (i.e. experts). For every token, at each layer, a router network selects two experts to process the current state and combine their outputs. Even though each token only sees two experts, the selected experts can be different at each timestep. As a result, each token has access to 47B parameters, but only uses 13B active parameters during inference. Mixtral was trained with a context size of 32k tokens and it outperforms or matches Llama 2 70B and GPT-3.5 across all evaluated benchmarks. In particular, Mixtral vastly outperforms Llama 2 70B on mathematics, code generation, and multilingual benchmarks. We also provide a model fine- tuned to follow instructions, Mixtral 8x7B â\\x80\\x93 Instruct, that surpasses GPT-3.5 Turbo, Claude-2.1, Gemini Pro, and Llama 2 70B â\\x80\\x93 chat model on human bench- marks. Both the base and instruct models are released under the Apache 2.0 license.\\nCode: https://github.com/mistralai/mistral-src Webpage: https://mistral.ai/news/mixtral-of-experts/\\n# Introduction\\nIn this paper, we present Mixtral 8x7B, a sparse mixture of experts model (SMoE) with open weights, licensed under Apache 2.0. Mixtral outperforms Llama 2 70B and GPT-3.5 on most benchmarks. As it only uses a subset of its parameters for every token, Mixtral allows faster inference speed at low batch-sizes, and higher throughput at large batch-sizes.\\nMixtral is a sparse mixture-of-experts network. It is a decoder-only model where the feedforward block picks from a set of 8 distinct groups of parameters. At every layer, for every token, a router network chooses two of these groups (the â\\x80\\x9cexpertsâ\\x80\\x9d) to process the token and combine their output additively. This technique increases the number of parameters of a model while controlling cost and latency, as the model only uses a fraction of the total set of parameters per token.\\nMixtral is pretrained with multilingual data using a context size of 32k tokens. It either matches or exceeds the performance of Llama 2 70B and GPT-3.5, over several benchmarks. In particular,\\nMixture of Experts Layer i gating inputs af outputs router expert\\nFigure 1: Mixture of Experts Layer. Each input vector is assigned to 2 of the 8 experts by a router. The layerâ\\x80\\x99s output is the weighted sum of the outputs of the two selected experts. In Mixtral, an expert is a standard feedforward block as in a vanilla transformer architecture.\\nMixtral demonstrates superior capabilities in mathematics, code generation, and tasks that require multilingual understanding, significantly outperforming Llama 2 70B in these domains. Experiments show that Mixtral is able to successfully retrieve information from its context window of 32k tokens, regardless of the sequence length and the location of the information in the sequence.\\nWe also present Mixtral 8x7B â\\x80\\x93 Instruct, a chat model fine-tuned to follow instructions using supervised fine-tuning and Direct Preference Optimization [25]. Its performance notably surpasses that of GPT-3.5 Turbo, Claude-2.1, Gemini Pro, and Llama 2 70B â\\x80\\x93 chat model on human evaluation benchmarks. Mixtral â\\x80\\x93 Instruct also demonstrates reduced biases, and a more balanced sentiment profile in benchmarks such as BBQ, and BOLD. We release both Mixtral 8x7B and Mixtral 8x7B â\\x80\\x93 Instruct under the Apache 2.0 license1, free for academic and commercial usage, ensuring broad accessibility and potential for diverse applications. To enable the community to run Mixtral with a fully open-source stack, we submitted changes to the vLLM project, which integrates Megablocks CUDA kernels for efficient inference. Skypilot also allows the deployment of vLLM endpoints on any instance in the cloud.\\n# 2 Architectural details\\nMixtral is based on a transformer architecture [31] and uses the same modifications as described in [18], with the notable exceptions that Mix- tral supports a fully dense context length of 32k tokens, and the feed- forward blocks are replaced by Mixture-of-Expert layers (Section 2.1). The model architecture parameters are summarized in Table 1. Parameter Value\\ndim n_layers head_dim hidden_dim n_heads n_kv_heads context_len vocab_size num_experts top_k_experts\\n# 2.1 Sparse Mixture of Experts\\nWe present a brief overview of the Mixture of Experts layer (Figure 1). For a more in-depth overview, see [12]. The output of the MoE module for a given input x is determined by the weighted sum of the outputs of the expert networks, where the weights are given by the gating networkâ\\x80\\x99s output. i.e. given n expert networks {E0, Ei, ..., Enâ\\x88\\x921}, the output of the expert layer is given by: Table 1: Model architecture.\\n# j nâ\\x80\\x94\\nG(x)i Â· Ei(x). i=0\\nHere, G(x)i denotes the n-dimensional output of the gating network for the i-th expert, and Ei(x) is the output of the i-th expert network. If the gating vector is sparse, we can avoid computing the outputs of experts whose gates are zero. There are multiple alternative ways of implementing G(x) [6, 15, 35], but a simple and performant one is implemented by taking the softmax over the Top-K logits of a linear layer [28]. We use\\nG(x) := Softmax(TopK(x Â· Wg)),\\nwhere (TopK(â\\x84\\x93))i := â\\x84\\x93i if â\\x84\\x93i is among the top-K coordinates of logits â\\x84\\x93 â\\x88\\x88 Rn and (TopK(â\\x84\\x93))i := â\\x88\\x92â\\x88\\x9e otherwise. The value of K â\\x80\\x93 the number of experts used per token â\\x80\\x93 is a hyper-parameter that modu- lates the amount of compute used to process each token. If one increases n while keeping K fixed, one\\n# 1https://mistral.ai/news/mixtral-of-experts/\\n2\\n4096 32 128 14336 32 8 32768 32000 8 2\\ncan increase the modelâ\\x80\\x99s parameter count while keeping its computational cost effectively constant. This motivates a distinction between the modelâ\\x80\\x99s total parameter count (commonly referenced as the sparse parameter count), which grows with n, and the number of parameters used for processing an individual token (called the active parameter count), which grows with K up to n.\\nMoE layers can be run efficiently on single GPUs with high performance specialized kernels. For example, Megablocks [13] casts the feed-forward network (FFN) operations of the MoE layer as large sparse matrix multiplications, significantly enhancing the execution speed and naturally handling cases where different experts get a variable number of tokens assigned to them. Moreover, the MoE layer can be distributed to multiple GPUs through standard Model Parallelism techniques, and through a particular kind of partitioning strategy called Expert Parallelism (EP) [28]. During the MoE layerâ\\x80\\x99s execution, tokens meant to be processed by a specific expert are routed to the corresponding GPU for processing, and the expertâ\\x80\\x99s output is returned to the original token location. Note that EP introduces challenges in load balancing, as it is essential to distribute the workload evenly across the GPUs to prevent overloading individual GPUs or hitting computational bottlenecks.\\nIn a Transformer model, the MoE layer is applied independently per token and replaces the feed-forward (FFN) sub-block of the transformer block. For Mixtral we use the same SwiGLU architecture as the expert function Ei(x) and set K = 2. This means each token is routed to two SwiGLU sub-blocks with different sets of weights. Taking this all together, the output y for an input token x is computed as:\\nn-1 y= Ss Softmax(Top2(a - W,)); - SwiGLU;(a). i=0\\nThis formulation is similar to the GShard architecture [21], with the exceptions that we replace all FFN sub-blocks by MoE layers while GShard replaces every other block, and that GShard uses a more elaborate gating strategy for the second expert assigned to each token.\\n# 3 Results\\nWe compare Mixtral to Llama, and re-run all benchmarks with our own evaluation pipeline for fair comparison. We measure performance on a wide variety of tasks categorized as follow:\\nâ\\x80¢ Commonsense Reasoning (0-shot): Hellaswag [32], Winogrande [26], PIQA [3], SIQA [27], OpenbookQA [22], ARC-Easy, ARC-Challenge [8], CommonsenseQA [30]\\nWorld Knowledge (5-shot): NaturalQuestions [20], TriviaQA [19] â\\x80¢ Reading Comprehension (0-shot): BoolQ [7], QuAC [5] â\\x80¢ Math: GSM8K [9] (8-shot) with maj@8 and MATH [17] (4-shot) with maj@4 â\\x80¢ Code: Humaneval [4] (0-shot) and MBPP [1] (3-shot) â\\x80¢ Popular aggregated results: MMLU [16] (5-shot), BBH [29] (3-shot), and AGI Eval [34]\\n(3-5-shot, English multiple-choice questions only)\\n80 SE Mistral 78 = LLaMA27B = Sl LLaMA134B, jam Mistral 78 = LlaMA27B Ss LLAMA 1348, cee Mixtral 8x78 Sm LLaMA213BÂ° mmm LLaMA2 70B je Mixtral 8x78 mm LlaMA2138 lm LLaMA2 708 70 50 60 50 20 40 10 BH Code MMU Knowledge Reasoning â\\x80\\x98Comprehension AGI Eval Math â\\x80\\x98Accuracy (%)\\nFigure 2: Performance of Mixtral and different Llama models on a wide range of benchmarks. All models were re-evaluated on all metrics with our evaluation pipeline for accurate comparison. Mixtral outperforms or matches Llama 2 70B on all benchmarks. In particular, it is vastly superior in mathematics and code generation.\\n3\\nActive Params MMLU HellaS WinoG PIQA Arc-e Arc-c NQ TriQA HumanE MBPP Math GSM8K 7B 44.4% 77.1% 69.5% 77.9% 68.7% 43.2% 17.5% 56.6% 11.6% 26.1% 3.9% 16.0% 13B 55.6% 80.7% 72.9% 80.8% 75.2% 48.8% 16.7% 64.0% 18.9% 35.4% 6.0% 34.3% 33B 56.8% 83.7% 76.2% 82.2% 79.6% 54.4% 24.1% 68.5% 25.0% 40.9% 8.4% 44.1% 70B 69.9% 85.4% 80.4% 82.6% 79.9% 56.5% 25.4% 73.0% 29.3% 49.8% 13.8% 69.6% 7B 62.5% 81.0% 74.2% 82.2% 80.5% 54.9% 23.2% 62.5% 26.2% 50.2% 12.7% 50.0% 13B 70.6% 84.4% 77.2% 83.6% 83.1% 59.7% 30.6% 71.5% 40.2% 60.7% 28.4% 74.4%\\nTable 2: Comparison of Mixtral with Llama. Mixtral outperforms or matches Llama 2 70B performance on almost all popular benchmarks while using 5x fewer active parameters during inference.\\n70 Mixtral 8x7B. â\\x80\\x98Mixtral 8x7B Mixtral 8x7B 355 =o = Es & E60! Mistral 78 % 2681 Mistral 78 3 3 s0 5 = A % 66 50 g 4 45 64 78 138 348708 78 138 348708 78 138 348 70B S66 Mixtral 8x7B 50 Mixtral 8x7B 5 = 564 340 g al Mistral 78 ee Mistral 78 3 5 Â§ 30 5 eo â\\x80\\x94= Mistral Â° 20 â\\x80\\x94e LlaMA2 78 (138 348 70B 7B (138 348 708 7B Â«13B 34B 708 Active Params Active Params Active Params\\nFigure 3: Results on MMLU, commonsense reasoning, world knowledge and reading comprehension, math and code for Mistral (7B/8x7B) vs Llama 2 (7B/13B/70B). Mixtral largely outperforms Llama 2 70B on all benchmarks, except on reading comprehension benchmarks while using 5x lower active parameters. It is also vastly superior to Llama 2 70B on code and math.\\nDetailed results for Mixtral, Mistral 7B and Llama 2 7B/13B/70B and Llama 1 34B2 are reported in Table 2. Figure 2 compares the performance of Mixtral with the Llama models in different categories. Mixtral surpasses Llama 2 70B across most metrics. In particular, Mixtral displays a superior performance in code and mathematics benchmarks.\\nSize and Efficiency. We compare our performance to the Llama 2 family, aiming to understand Mixtral modelsâ\\x80\\x99 efficiency in the cost-performance spectrum (see Figure 3). As a sparse Mixture- of-Experts model, Mixtral only uses 13B active parameters for each token. With 5x lower active parameters, Mixtral is able to outperform Llama 2 70B across most categories.\\nNote that this analysis focuses on the active parameter count (see Section 2.1), which is directly proportional to the inference compute cost, but does not consider the memory costs and hardware utilization. The memory costs for serving Mixtral are proportional to its sparse parameter count, 47B, which is still smaller than Llama 2 70B. As for device utilization, we note that the SMoEs layer introduces additional overhead due to the routing mechanism and due to the increased memory loads when running more than one expert per device. They are more suitable for batched workloads where one can reach a good degree of arithmetic intensity.\\nComparison with Llama 2 70B and GPT-3.5. In Table 3, we report the performance of Mixtral 8x7B compared to Llama 2 70B and GPT-3.5. We observe that Mixtral performs similarly or above the two other models. On MMLU, Mixtral obtains a better performance, despite its significantly smaller capacity (47B tokens compared to 70B). For MT Bench, we report the performance of the latest GPT-3.5-Turbo model available, gpt-3.5-turbo-1106.\\n2Since Llama 2 34B was not open-sourced, we report results for Llama 1 34B.\\n4\\nLLaMA 2 70B GPT-3.5 MMLU (MCQ in 57 subjects) 69.9% 70.0% 70.6% HellaSwag (10-shot) 87.1% 85.5% 86.7% ARC Challenge (25-shot) 85.1% 85.2% 85.8% WinoGrande (5-shot) 83.2% 81.6% 81.2% MBPP (pass@1) 49.8% 52.2% 60.7% GSM-8K (5-shot) 53.6% 57.1% 58.4% MT Bench (for Instruct Models) 6.86 8.32 8.30\\n# Mixtral 8x7B\\nTable 3: Comparison of Mixtral with Llama 2 70B and GPT-3.5. Mixtral outperforms or matches Llama 2 70B and GPT-3.5 performance on most metrics.\\nEvaluation Differences. On some benchmarks, there are some differences between our evaluation protocol and the one reported in the Llama 2 paper: 1) on MBPP, we use the hand-verified subset 2) on TriviaQA, we do not provide Wikipedia contexts.\\n# 3.1 Multilingual benchmarks\\nCompared to Mistral 7B, we significantly upsample the proportion of multilingual data during pretraining. The extra capacity allows Mixtral to perform well on multilingual benchmarks while maintaining a high accuracy in English. In particular, Mixtral significantly outperforms Llama 2 70B in French, German, Spanish, and Italian, as shown in Table 4.\\nActive Params French Arc-c HellaS MMLU German Arc-c HellaS MMLU Spanish Arc-c HellaS MMLU Italian Arc-c HellaS MMLU 33B 70B 13B 42.9% 65.4% 49.0% 39.3% 68.1% 49.9% 49.9% 72.5% 64.3% 49.4% 70.9% 65.1% 58.2% 77.4% 70.9% 54.3% 73.0% 71.5% 55.4% 77.6% 72.5% 52.8% 75.1% 70.9% 41.1% 63.3% 48.7% 47.3% 68.7% 64.2% 45.7% 69.8% 52.3% 50.5% 74.5% 66.0%\\nTable 4: Comparison of Mixtral with Llama on Multilingual Benchmarks. On ARC Challenge, Hellaswag, and MMLU, Mixtral outperforms Llama 2 70B on 4 languages: French, German, Spanish, and Italian.\\n# 3.2 Long range performance\\nTo assess the capabilities of Mixtral to tackle long context, we evaluate it on the passkey retrieval task introduced in [23], a synthetic task designed to measure the ability of the model to retrieve a passkey inserted randomly in a long prompt. Results in Figure 4 (Left) show that Mixtral achieves a 100% retrieval accuracy regardless of the context length or the position of passkey in the sequence. Figure 4 (Right) shows that the perplexity of Mixtral on a subset of the proof-pile dataset [2] decreases monotonically as the size of the context increases.\\nPasskey Performance ry 0.8 0.6 04 0.2 0.0 OK 4K 8K 12K 16K 20K 24K 28K Seq Len Passkey Loc\\n3.8 â\\x80\\x94 Mixtral_8x7B 3.5 32 > $3.0 i] 228 fos a 2.0 0 5k 10k 15k 20k 25k 30k Context length\\nPasskey Performance ry 3.8 â\\x80\\x94 Mixtral_8x7B 3.5 0.8 32 > 0.6 $3.0 i] 228 04 fos 0.2 a 2.0 0.0 OK 4K 8K 12K 16K 20K 24K 28K 0 5k 10k 15k 20k 25k 30k Seq Len Context length\\nFigure 4: Long range performance of Mixtral. (Left) Mixtral has 100% retrieval accuracy of the Passkey task regardless of the location of the passkey and length of the input sequence. (Right) The perplexity of Mixtral on the proof-pile dataset decreases monotonically as the context length increases.\\n5\\n# 3.3 Bias Benchmarks\\nTo identify possible flaws to be corrected by fine-tuning / preference modeling, we measure the base model performance on Bias Benchmark for QA (BBQ) [24] and Bias in Open-Ended Language Generation Dataset (BOLD) [10]. BBQ is a dataset of hand-written question sets that target attested social biases against nine differ- ent socially-relevant categories: age, dis- ability status, gender identity, nationality, physical appearance, race/ethnicity, religion, socio-economic status, sexual orientation. BOLD is a large-scale dataset that consists of 23,679 English text generation prompts for bias benchmarking across five domains.\\nLlama 2 70B Mixtral 8x7B BBQ accuracy 51.5% 56.0% BOLD sentiment score (avg Â± std) gender profession religious_ideology political_ideology race 0.293 Â± 0.073 0.218 Â± 0.073 0.188 Â± 0.133 0.149 Â± 0.140 0.232 Â± 0.049 0.323 Â±0.045 0.243 Â± 0.087 0.144 Â± 0.089 0.186 Â± 0.146 0.232 Â± 0.052\\nFigure 5: Bias Benchmarks. Compared Llama 2 70B, Mixtral presents less bias (higher accuracy on BBQ, lower std on BOLD) and displays more positive sentiment (higher avg on BOLD).\\nWe benchmark Llama 2 and Mixtral on BBQ and BOLD with our evaluation framework and report the results in Table 5. Compared to Llama 2, Mixtral presents less bias on the BBQ benchmark (56.0% vs 51.5%). For each group in BOLD, a higher average sentiment score means more positive sentiments and a lower standard deviation indicates less bias within the group. Overall, Mixtral displays more positive sentiments than Llama 2, with similar variances within each group.\\n# Instruction Fine-tuning\\nWe train Mixtral â\\x80\\x93 Instruct using supervised fine-tuning (SFT) on an instruction dataset followed by Direct Preference Optimization (DPO) [25] on a paired feedback dataset. Mixtral â\\x80\\x93 Instruct reaches a score of 8.30 on MT-Bench [33] (see Table 2), making it the best open-weights model as of December 2023. Independent human evaluation conducted by LMSys is reported in Figure 63 and shows that Mixtral â\\x80\\x93 Instruct outperforms GPT-3.5-Turbo, Gemini Pro, Claude-2.1, and Llama 2 70B chat.\\nvs Arena Elo rating 1 MT-bench (score) License 1243 9.32 Proprietary 1192 8.96 Proprietary 1158 9.18 Proprietary Glaude-4 1149 7.9 Proprietary Claude-2.0 1131 8.06 Proprietary 1121 eS) Apache 2.0 Glaude-2.4 1117 8.18 Proprietary GPT-3..5-Turbo-9613 1117 8.39 Proprietary Gemini..Pro 1141 Proprietary Glas ta 1110 7.85 Proprietary Tulu-2-0P0-708 1110 7.89 AI2 ImpACT Low-risk Yi-34B-Chat 1110 Yi License GPT-3.5:Turbo-0314 1105 7.94 Proprietary Llama-2-79b-chat 1077 6.86 Llama 2 Community\\nFigure 6: LMSys Leaderboard. (Screenshot from Dec 22, 2023) Mixtral 8x7B Instruct v0.1 achieves an Arena Elo rating of 1121 outperforming Claude-2.1 (1117), all versions of GPT-3.5-Turbo (1117 best), Gemini Pro (1111), and Llama-2-70b-chat (1077). Mixtral is currently the best open-weights model by a large margin.\\n3https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard\\n6\\n# 5 Routing analysis\\nIn this section, we perform a small analysis on the expert selection by the router. In particular, we are interested to see if during training some experts specialized to some specific domains (e.g. mathematics, biology, philosophy, etc.).\\nTo investigate this, we measure the distribution of selected experts on different subsets of The Pile validation dataset [14]. Results are presented in Figure 7, for layers 0, 15, and 31 (layers 0 and 31 respectively being the first and the last layers of the model). Surprisingly, we do not observe obvious patterns in the assignment of experts based on the topic. For instance, at all layers, the distribution of expert assignment is very similar for ArXiv papers (written in Latex), for biology (PubMed Abstracts), and for Philosophy (PhilPapers) documents.\\nOnly for DM Mathematics we note a marginally different distribution of experts. This divergence is likely a consequence of the datasetâ\\x80\\x99s synthetic nature and its limited coverage of the natural language spectrum, and is particularly noticeable at the first and last layers, where the hidden states are very correlated to the input and output embeddings respectively.\\nThis suggests that the router does exhibit some structured syntactic behavior. Figure 8 shows examples of text from different domains (Python code, mathematics, and English), where each token is highlighted with a background color corresponding to its selected expert. The figure shows that words such as â\\x80\\x98selfâ\\x80\\x99 in Python and â\\x80\\x98Questionâ\\x80\\x99 in English often get routed through the same expert even though they involve multiple tokens. Similarly, in code, the indentation tokens are always assigned to the same experts, particularly at the first and last layers where the hidden states are more correlated to the input and output of the model.\\nWe also note from Figure 8 that consecutive tokens are often assigned the same experts. In fact, we observe some degree of positional locality in The Pile datasets. Table 5 shows the proportion of con- secutive tokens that get the same expert assignments per domain and layer. The proportion of repeated\\n0.20 0.15 0.10 0.05 layer: 15 0.20 0.15 0.10 0.05 layer: 31 Selection proportion 0.20 0.15 0.10 0.05 Expert ID | | ArXiv | Github | | PhilPapers | StackExchange | | DM Mathematics | | Gutenberg | | PubMed Abstracts | | Wikipedia (en)\\nFigure 7: Proportion of tokens assigned to each expert on different domains from The Pile dataset for layers 0, 15, and 31. The gray dashed vertical line marks 1/8, i.e. the proportion expected with uniform sampling. Here, we consider experts that are either selected as a first or second choice by the router. A breakdown of the proportion of assignments done in each case cane be seen in Figure 9 in the Appendix.\\n7\\nLayer 0 First choice Layer 15 Layer 31 Layer 0 First or second choice Layer 15 Layer 31 ArXiv DM Mathematics Github Gutenberg PhilPapers PubMed Abstracts StackExchange Wikipedia (en) 14.0% 14.1% 14.9% 13.9% 13.6% 14.2% 13.6% 14.4% 27.9% 28.4% 28.1% 26.1% 25.3% 24.6% 27.2% 23.6% 22.7% 19.7% 19.7% 26.3% 22.1% 22.0% 23.6% 25.3% 46.5% 44.9% 49.9% 49.5% 46.9% 48.6% 48.2% 49.8% 62.3% 67.0% 66.9% 63.1% 61.9% 61.6% 64.6% 62.1% 52.9% 44.5% 49.2% 52.2% 51.3% 51.8% 53.6% 51.8%\\nTable 5: Percentage of expert assignment repetitions. We evaluate the proportion of times the same expert is assigned to a token i and its following token i+1. We report whether the first chosen expert is the same, or whether the same expert is observed as first or second choice in consecutive tokens. For reference, the expected proportion of repetitions in the case of random assignments is 1 5 7 â\\x89\\x88 46% for â\\x80\\x9cFirst and second choiceâ\\x80\\x9d. Repetitions at the first layer are close to random, but are significantly higher at layers 15 and 31. The high number of repetitions shows that expert choice exhibits high temporal locality at these layers.\\nconsecutive assignments is significantly higher than random for higher layers. This has implications in how one might optimize the model for fast training and inference. For example, cases with high locality are more likely to cause over-subscription of certain experts when doing Expert Parallelism. Conversely, this locality can be leveraged for caching, as is done in [11]. A more complete view of these same expert frequency is provided for all layers and across datasets in Figure 10 in the Appendix.\\n# 6 Conclusion\\nIn this paper, we introduced Mixtral 8x7B, the first mixture-of-experts network to reach a state-of-the- art performance among open-source models. Mixtral 8x7B Instruct outperforms Claude-2.1, Gem- ini Pro, and GPT-3.5 Turbo on human evaluation benchmarks. Because it only uses two experts at each time step, Mixtral only uses 13B active parameters per token while outperforming the previous best model using 70B parameters per token (Llama 2 70B). We are making our trained and fine-tuned mod- els publicly available under the Apache 2.0 license. By sharing our models, we aim to facilitate the de- velopment of new techniques and applications that can benefit a wide range of industries and domains.\\nLayer 0 Layer 15 Layer 31 class MoeLayer(nn. Module) : â\\x80\\x9cinit__(self, experts//List [nn.Modutel,) | Super (V7 init assert len(experts) > 0 self. experts = nn.ModuleList((experts) self. gate = gate self.args = moe_args def forward(self, inputs: torch.Tensor): inputs _squashed = inputs. view(-1,_ inputs.| gate_logits = self.gatel inputs_squashed) weights, selected_experts = torch. topk( gate_logits, Self-args.nun_experts_Ã© weights! = nri.|funct ional softinax'( weights, din=1, dtype=torch. float, ).type_as|(inputs) results| = torch. zeros_ ike! linputs_squashe for i, expert in enunerate(self. experts): batch_idx,! nth_expert = torch. wnere( results [batch_idx] += weights [batch_i input s_squashed [batch_idx] ) return resutts:.view las{(inputs) class NoeLayer (nn. Module) = def _ init__(self, experts! List'{nri.Modulelly Super (Tz init_t assert len (experts) > 9) self.experts = nn. ModuleList((experits)) def forward(self, inputs: torch. Tensor)?! inputs_squashed = inputs.View(-1) inputs) gate_logits = self.gatel inputs_squashed) weights, selected_experts = torch. topk( getellogits, self.argssnun_experts pe weightsâ\\x80\\x99 = nn. functionallsoftmax(Â® Weights, dtypextorch. floaty ) type_as (inputs) results| = torch. zerdsillikel(input siiequashe| for i, expert in enumerate (self. experts): batch idx, nth_expert = torch.where(s results [batch_idx] += weights [batch_iÂ¢ inputs|_squashed[batch idx], y return resultsiiview jas (inputs) class| MoeLayer(nn. Module): def init__(self, expertsâ\\x80\\x99 List|fifi.Modulel) Super(Ve_init_O) assert len(experts) > 0 self, experts = nn.ModuleListl(@xperits)) self. gate = gate Self.args = moe_args def forward(self, inputs: torch. Tensor): inputs_squashed = inputs.view(=1, inputs) gate_logits = self.gate( inputs_squashed) weights, selected_experts = torch. topk( gate_logits, self.argssfum_experts_pe weights) nni.unct iorial.isoftinax( YP Yiitype_as (inputs) results = torch. zerosillikel(inputslisquashe| for i, expert in enunerate(self.experts): batch_idx, nth_expert = torch.where(s results [batch_idx] += weights [batch_iÂ¢ inputs_squashed [batch_idx] ) return) results\\\\iviewilas|(inputs)) Tuestiond] Solve â\\x80\\x94AINr 27K SLIT! and SORT, lanswers 4 Question?â\\x80\\x99 Calculate Baiasoazusaaly 4111270 iAnswer: -841469015.544 (Question! Letâ\\x80\\x99 x(gy = 94g # Hl Let! q(clJ= Zee #] IAnswer: S4ea - 30 â\\x80\\x98Question#! Solve Azer Â¥ 27HE = Ate and 1505 lanswer:) 4 Calculate ~eaieseiaz. saa Â¥ 417127. ~841469015.544 â\\x80\\x98Answer: (Questor â\\x80\\x98Answer: etâ\\x80\\x99 x(q) = 9*g Â¥ Wl Let! ql)! = 2eele Sara â\\x80\\x94 30 question Solve -42Â¥e1E B7eC= â\\x80\\x94Ad67 and 130%] answers \\\\questionÂ®| calculate savesona2.saq + auaz7. Answer: -847469015.544 â\\x80\\x98OÂ¥o)H A Let q(el = (questiond! Let! x(a) = awed | Answers 54a ~ â\\x80\\x98A model airplane flies stower when flying into tt jwind and faster with wind at its back. when Launcl Iright angles to the wind,â\\x80\\x9d cross wind,| its groun Icompared with! flying in still air is (A) the same (B) greater (C) less (0)! either! grea lor less dependingâ\\x80\\x99 on wind speed i nodelaitp ane) URE slover when flying into eH lind and faster with wind at its back. When) launch Tight angles to the wind, a cross wind,. its) grounc Compared with â\\x80\\x98lying in stitt air is (A) the same (18) greater) (C) less (D)! either grea lor less depending on wind speed H model airplane flies slower! when flying inte th wind and faster with wind at its backâ\\x80\\x99. When Launcl [right angles to the wind, a cross wind, its grounc Icompared with flying in still air is (A) the sane (B) greater (C) less (0)! either gree jor less depending on wind speed\\nFigure 8: Text samples where each token is colored with the first expert choice. The selection of experts appears to be more aligned with the syntax rather than the domain, especially at the initial and final layers.\\n8\\n# Acknowledgements\\nWe thank the CoreWeave and Scaleway teams for technical support as we trained our models. We are grateful to NVIDIA for supporting us in integrating TensorRT-LLM and Triton and working alongside us to make a sparse mixture of experts compatible with TensorRT-LLM.\\n# References\\n[1] Jacob Austin, Augustus Odena, Maxwell Nye, Maarten Bosma, Henryk Michalewski, David Dohan, Ellen Jiang, Carrie Cai, Michael Terry, Quoc Le, et al. Program synthesis with large language models. arXiv preprint arXiv:2108.07732, 2021.\\n[2] Zhangir Azerbayev, Hailey Schoelkopf, Keiran Paster, Marco Dos Santos, Stephen McAleer, Albert Q Jiang, Jia Deng, Stella Biderman, and Sean Welleck. Llemma: An open language model for mathematics. arXiv preprint arXiv:2310.10631, 2023.\\n[3] Yonatan Bisk, Rowan Zellers, Jianfeng Gao, Yejin Choi, et al. Piqa: Reasoning about phys- ical commonsense in natural language. In Proceedings of the AAAI conference on artificial intelligence, pages 7432â\\x80\\x937439, 2020.\\n[4] Mark Chen, Jerry Tworek, Heewoo Jun, Qiming Yuan, Henrique Ponde de Oliveira Pinto, Jared Kaplan, Harri Edwards, Yuri Burda, Nicholas Joseph, Greg Brockman, et al. Evaluating large language models trained on code. arXiv preprint arXiv:2107.03374, 2021.\\n[5] Eunsol Choi, He He, Mohit Iyyer, Mark Yatskar, Wen-tau Yih, Yejin Choi, Percy Liang, and Luke Zettlemoyer. Quac: Question answering in context. arXiv preprint arXiv:1808.07036, 2018.\\n[6] Aidan Clark, Diego De Las Casas, Aurelia Guy, Arthur Mensch, Michela Paganini, Jordan Hoffmann, Bogdan Damoc, Blake Hechtman, Trevor Cai, Sebastian Borgeaud, et al. Unified scaling laws for routed language models. In International Conference on Machine Learning, pages 4057â\\x80\\x934086. PMLR, 2022.\\n[7] Christopher Clark, Kenton Lee, Ming-Wei Chang, Tom Kwiatkowski, Michael Collins, and Kristina Toutanova. Boolq: Exploring the surprising difficulty of natural yes/no questions. arXiv preprint arXiv:1905.10044, 2019.\\n[8] Peter Clark, Isaac Cowhey, Oren Etzioni, Tushar Khot, Ashish Sabharwal, Carissa Schoenick, and Oyvind Tafjord. Think you have solved question answering? try arc, the ai2 reasoning challenge. arXiv preprint arXiv:1803.05457, 2018.\\n[9] Karl Cobbe, Vineet Kosaraju, Mohammad Bavarian, Mark Chen, Heewoo Jun, Lukasz Kaiser, Matthias Plappert, Jerry Tworek, Jacob Hilton, Reiichiro Nakano, et al. Training verifiers to solve math word problems. arXiv preprint arXiv:2110.14168, 2021.\\n[10] Jwala Dhamala, Tony Sun, Varun Kumar, Satyapriya Krishna, Yada Pruksachatkun, Kai-Wei Chang, and Rahul Gupta. Bold: Dataset and metrics for measuring biases in open-ended language generation. In Proceedings of the 2021 ACM conference on fairness, accountability, and transparency, pages 862â\\x80\\x93872, 2021.\\n[11] Artyom Eliseev and Denis Mazur. Fast inference of mixture-of-experts language models with offloading. arXiv preprint arXiv:2312.17238, 2023.\\n[12] William Fedus, Jeff Dean, and Barret Zoph. A review of sparse expert models in deep learning. arXiv preprint arXiv:2209.01667, 2022.\\n[13] Trevor Gale, Deepak Narayanan, Cliff Young, and Matei Zaharia. Megablocks: Efficient sparse training with mixture-of-experts. arXiv preprint arXiv:2211.15841, 2022.\\n[14] Leo Gao, Stella Biderman, Sid Black, Laurence Golding, Travis Hoppe, Charles Foster, Jason Phang, Horace He, Anish Thite, Noa Nabeshima, et al. The pile: An 800gb dataset of diverse text for language modeling. arXiv preprint arXiv:2101.00027, 2020.\\n[15] Hussein Hazimeh, Zhe Zhao, Aakanksha Chowdhery, Maheswaran Sathiamoorthy, Yihua Chen, Rahul Mazumder, Lichan Hong, and Ed Chi. Dselect-k: Differentiable selection in the mixture of experts with applications to multi-task learning. Advances in Neural Information Processing Systems, 34:29335â\\x80\\x9329347, 2021.\\n9\\n[16] Dan Hendrycks, Collin Burns, Steven Basart, Andy Zou, Mantas Mazeika, Dawn Song, and Jacob Steinhardt. Measuring massive multitask language understanding. arXiv preprint arXiv:2009.03300, 2020.\\n[17] Dan Hendrycks, Collin Burns, Saurav Kadavath, Akul Arora, Steven Basart, Eric Tang, Dawn Song, and Jacob Steinhardt. Measuring mathematical problem solving with the math dataset. arXiv preprint arXiv:2103.03874, 2021.\\n[18] Albert Q Jiang, Alexandre Sablayrolles, Arthur Mensch, Chris Bamford, Devendra Singh Chaplot, Diego de las Casas, Florian Bressand, Gianna Lengyel, Guillaume Lample, Lucile Saulnier, et al. Mistral 7b. arXiv preprint arXiv:2310.06825, 2023.\\n[19] Mandar Joshi, Eunsol Choi, Daniel S Weld, and Luke Zettlemoyer. Triviaqa: A large scale distantly supervised challenge dataset for reading comprehension. arXiv preprint arXiv:1705.03551, 2017.\\n[20] Tom Kwiatkowski, Jennimaria Palomaki, Olivia Redfield, Michael Collins, Ankur Parikh, Chris Alberti, Danielle Epstein, Illia Polosukhin, Jacob Devlin, Kenton Lee, et al. Natural questions: a benchmark for question answering research. Transactions of the Association for Computational Linguistics, pages 453â\\x80\\x93466, 2019.\\n[21] Dmitry Lepikhin, HyoukJoong Lee, Yuanzhong Xu, Dehao Chen, Orhan Firat, Yanping Huang, Maxim Krikun, Noam Shazeer, and Zhifeng Chen. Gshard: Scaling giant models with condi- tional computation and automatic sharding. arXiv preprint arXiv:2006.16668, 2020.\\n[22] Todor Mihaylov, Peter Clark, Tushar Khot, and Ashish Sabharwal. Can a suit of armor conduct electricity? a new dataset for open book question answering. arXiv preprint arXiv:1809.02789, 2018.\\n[23] Amirkeivan Mohtashami and Martin Jaggi. Landmark attention: Random-access infinite context length for transformers. arXiv preprint arXiv:2305.16300, 2023.\\n[24] Alicia Parrish, Angelica Chen, Nikita Nangia, Vishakh Padmakumar, Jason Phang, Jana Thomp- son, Phu Mon Htut, and Samuel R Bowman. Bbq: A hand-built bias benchmark for question answering. arXiv preprint arXiv:2110.08193, 2021.\\n[25] Rafael Rafailov, Archit Sharma, Eric Mitchell, Stefano Ermon, Christopher D Manning, and Chelsea Finn. Direct preference optimization: Your language model is secretly a reward model. arXiv preprint arXiv:2305.18290, 2023.\\n[26] Keisuke Sakaguchi, Ronan Le Bras, Chandra Bhagavatula, and Yejin Choi. Winogrande: An adversarial winograd schema challenge at scale. Communications of the ACM, pages 99â\\x80\\x93106, 2021.\\n[27] Maarten Sap, Hannah Rashkin, Derek Chen, Ronan LeBras, and Yejin Choi. Socialiqa: Com- monsense reasoning about social interactions. arXiv preprint arXiv:1904.09728, 2019.\\n[28] Noam Shazeer, Azalia Mirhoseini, Krzysztof Maziarz, Andy Davis, Quoc Le, Geoffrey Hinton, and Jeff Dean. Outrageously large neural networks: The sparsely-gated mixture-of-experts layer. arXiv preprint arXiv:1701.06538, 2017.\\n[29] Mirac Suzgun, Nathan Scales, Nathanael SchÃ¤rli, Sebastian Gehrmann, Yi Tay, Hyung Won Chung, Aakanksha Chowdhery, Quoc V Le, Ed H Chi, Denny Zhou, , and Jason Wei. Challenging big-bench tasks and whether chain-of-thought can solve them. arXiv preprint arXiv:2210.09261, 2022.\\n[30] Alon Talmor, Jonathan Herzig, Nicholas Lourie, and Jonathan Berant. Commonsenseqa: A ques- tion answering challenge targeting commonsense knowledge. arXiv preprint arXiv:1811.00937, 2018.\\n[31] Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez, Å\\x81ukasz Kaiser, and Illia Polosukhin. Attention is all you need. Advances in neural information processing systems, 30, 2017.\\n[32] Rowan Zellers, Ari Holtzman, Yonatan Bisk, Ali Farhadi, and Yejin Choi. Hellaswag: Can a machine really finish your sentence? arXiv preprint arXiv:1905.07830, 2019.\\n[33] Lianmin Zheng, Wei-Lin Chiang, Ying Sheng, Siyuan Zhuang, Zhanghao Wu, Yonghao Zhuang, Zi Lin, Zhuohan Li, Dacheng Li, Eric Xing, et al. Judging llm-as-a-judge with mt-bench and chatbot arena. arXiv preprint arXiv:2306.05685, 2023.\\n10\\n[34] Wanjun Zhong, Ruixiang Cui, Yiduo Guo, Yaobo Liang, Shuai Lu, Yanlin Wang, Amin Saied, Weizhu Chen, and Nan Duan. Agieval: A human-centric benchmark for evaluating foundation models. arXiv preprint arXiv:2304.06364, 2023.\\n[35] Yanqi Zhou, Tao Lei, Hanxiao Liu, Nan Du, Yanping Huang, Vincent Zhao, Andrew M Dai, Quoc V Le, James Laudon, et al. Mixture-of-experts with expert choice routing. Advances in Neural Information Processing Systems, 35:7103â\\x80\\x937114, 2022.\\n11\\n# Either choice\\n0\\nLayer -- 0.3 0.2 0 Layer 0 -- First choice 0.3 Layer 0 -- Second choice 0.3 < 2 t Layer 15 -- First choice fe} Q 0.3 Â° a 0.2 el (el er rere! ie it len | ie} o 0 v Layer 15 -- Second choice 8 03 0.2 0 Layer 31 -- Either choice\\n# Expert ID\\nArXiv Github PhilPapers. StackExchange |_| | |_| | | DM Mathematics | Gutenberg || PubMed Abstracts | Wikipedia (en)\\nFigure 9: Proportion of tokens assigned to each expert on different subsets from The Pile dataset, separated by whether the expert was selected as first or second choice, or either. The â\\x80\\x9cEither choiceâ\\x80\\x9d case is equivalent to Figure 7. The gray dashed vertical line marks 1\\n12\\nFirst choice 9 w is) Â° N a Â° N is) Â° An wu 0.7 0.6 Proportion of repeated assignments 0.5 Layer source â\\x80\\x94e ArXiv â\\x80\\x94eâ\\x80\\x94 DM Mathematics â\\x80\\x94e Github â\\x80\\x94eâ\\x80\\x94 Gutenberg â\\x80\\x94eâ\\x80\\x94 PhilPapers â\\x80\\x94eâ\\x80\\x94 PubMed â\\x80\\x94e- StackExchange â\\x80\\x94e-â\\x80\\x94 Wikipedia (en)\\n# Abstracts\\nFigure 10: Repeated consecutive assignments per MoE layer. Repeated assignments occur a lot more often than they would with uniform assignments (materialized by the dashed lines). Patterns are similar across datasets with less repetitions for DM Mathematics.\\n13\",\n",
       " 'references': {'id': '1905.07830'}}"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Getting our Dataset: \n",
    "\n",
    "from datasets import load_dataset\n",
    "\n",
    "dataset = load_dataset(\"jamescalam/ai-arxiv2\", split=\"train\")\n",
    "\n",
    "#Let's take a peek at the data\n",
    "dataset[0]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 206
    },
    "id": "EI2iYxq16or9",
    "outputId": "55a8dd92-34e1-4237-a5c4-76016346999d"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "We introduce Mixtral 8x7B, a Sparse Mixture of Experts (SMoE) language model.\n",
      "Mixtral has the same architecture as Mistral 7B, with the difference that each\n",
      "layer is composed of 8 feedforward blocks (i.e. experts). For every token, at\n",
      "each layer, a router network selects two experts to process the current state\n",
      "and combine their outputs. Even though each token only sees two experts, the\n",
      "selected experts can be different at each timestep. As a result, each token has\n",
      "access to 47B parameters, but only uses 13B active parameters during inference.\n",
      "Mixtral was trained with a context size of 32k tokens and it outperforms or\n",
      "matches Llama 2 70B and GPT-3.5 across all evaluated benchmarks. In particular,\n",
      "Mixtral vastly outperforms Llama 2 70B on mathematics, code generation, and\n",
      "multilingual benchmarks. We also provide a model fine-tuned to follow\n",
      "instructions, Mixtral 8x7B - Instruct, that surpasses GPT-3.5 Turbo,\n",
      "Claude-2.1, Gemini Pro, and Llama 2 70B - chat model on human benchmarks. Both\n",
      "the base and instruct models are released under the Apache 2.0 license.\n"
     ]
    }
   ],
   "source": [
    "print(dataset[0][\"summary\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Lfd9lu6JbwoF"
   },
   "source": [
    "## Retrieval\n",
    "\n",
    "### Setting up Access\n",
    "\n",
    "Now the data is ready, we can set up our indexes to store it.\n",
    "\n",
    "We begin by instantiating a Pinecone client. To do this we need a [free API key](https://app.pinecone.io). We'll also setup our OpenAI API key at this time, so be sure to use one from your account."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Pinecone API key not found in environment.\n"
     ]
    }
   ],
   "source": [
    "\n",
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "def get_pinecone_api_key():\n",
    "    \"\"\"\n",
    "    Get Pinecone API key from environment variable or prompt user for input.\n",
    "    Returns the API key as a string.\n",
    "\n",
    "    Only necessary for notebooks. When using Pinecone yourself, \n",
    "    you can use environment variables or the like to set your API key.\n",
    "    \"\"\"\n",
    "    api_key = os.environ.get(\"PINECONE_API_KEY\")\n",
    "    \n",
    "    if api_key is None:\n",
    "        try:\n",
    "            # Try Colab authentication if available\n",
    "            from pinecone_notebooks.colab import Authenticate\n",
    "            Authenticate()\n",
    "            # If successful, key will now be in environment\n",
    "            api_key = os.environ.get(\"PINECONE_API_KEY\")\n",
    "        except ImportError:\n",
    "            # If not in Colab or authentication fails, prompt user for API key\n",
    "            print(\"Pinecone API key not found in environment.\")\n",
    "            api_key = getpass(\"Please enter your Pinecone API key: \")\n",
    "            # Save to environment for future use in session\n",
    "            os.environ[\"PINECONE_API_KEY\"] = api_key\n",
    "    \n",
    "    return api_key\n",
    "\n",
    "PINECONE_API_KEY = get_pinecone_api_key()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_openai_api_key():\n",
    "    \"\"\"\n",
    "    Get OpenAI API key from environment variable or prompt user for input.\n",
    "    Returns the API key as a string.\n",
    "    \"\"\"\n",
    "\n",
    "    api_key = os.environ.get(\"OPENAI_API_KEY\")\n",
    "    \n",
    "    if api_key is None:\n",
    "        try:\n",
    "            api_key = getpass(\"Please enter your OpenAI API key: \")\n",
    "            # Save to environment for future use in session\n",
    "            os.environ[\"OPENAI_API_KEY\"] = api_key\n",
    "        except Exception as e:\n",
    "            print(f\"Error getting OpenAI API key: {e}\")\n",
    "            return None\n",
    "    \n",
    "    return api_key\n",
    "\n",
    "OPENAI_API_KEY = get_openai_api_key()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Setting up our indexes\n",
    "\n",
    "Now that we have API keys, we can setup our indexes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "KPXw1sEubwoF"
   },
   "outputs": [],
   "source": [
    "from pinecone import Pinecone\n",
    "\n",
    "# Configure client\n",
    "pc = Pinecone(\n",
    "        api_key=PINECONE_API_KEY,\n",
    "        # You can remove this parameter for your own projects\n",
    "        source_tag=\"pinecone_examples:docs:gen_qa_openai\"\n",
    "    )\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since we are using a dense and a sparse model, we'll need separate indexes to store embeddings created by each model. Fortunately, we can use Pinecone Integrated Inference to do this easily:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "UPNwQTH0RNcl",
    "outputId": "954a84ba-cc9c-4796-fd12-28920024470c"
   },
   "outputs": [],
   "source": [
    "\n",
    "dense_index_name = 'gen-qa-openai-fast-dense'\n",
    "sparse_index_name = 'gen-qa-openai-fast-sparse'\n",
    "\n",
    "\n",
    "if not pc.has_index(dense_index_name):\n",
    "    pc.create_index_for_model(\n",
    "        name=dense_index_name,\n",
    "        cloud=\"aws\",\n",
    "        region=\"us-east-1\",\n",
    "        embed={\n",
    "            \"model\":\"llama-text-embed-v2\",\n",
    "            \"field_map\":{\"text\": \"chunk_text\"}\n",
    "        }\n",
    "    )\n",
    "\n",
    "if not pc.has_index(sparse_index_name):\n",
    "    pc.create_index_for_model(\n",
    "        name=sparse_index_name,\n",
    "        cloud=\"aws\",\n",
    "        region=\"us-east-1\",\n",
    "        embed={\n",
    "            \"model\":\"pinecone-sparse-english-v0\",\n",
    "            \"field_map\":{\"text\": \"chunk_text\"}\n",
    "        }\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, whenever we upsert or query to an index, it will automatically identify and call the appropriate model to embed our data with.\n",
    "\n",
    "To learn more about the strengths of our sparse model, [reference this article here](https://www.pinecone.io/learn/learn-pinecone-sparse/). To learn generally how dense models are trained and why, [check out our guide here](https://www.pinecone.io/learn/the-practitioners-guide-to-e5/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preprocess our dataset\n",
    "\n",
    "We'll need to reorient our dataset to the records format, to support using Pinecone Integrated Inference.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset = dataset.remove_columns([\"content\", \"comment\", \"journal_ref\", \"references\"])\n",
    "dataset = dataset.rename_column(\"summary\", \"chunk_text\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset=dataset.to_list()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'id': '2401.04088',\n",
       " 'title': 'Mixtral of Experts',\n",
       " 'chunk_text': 'We introduce Mixtral 8x7B, a Sparse Mixture of Experts (SMoE) language model.\\nMixtral has the same architecture as Mistral 7B, with the difference that each\\nlayer is composed of 8 feedforward blocks (i.e. experts). For every token, at\\neach layer, a router network selects two experts to process the current state\\nand combine their outputs. Even though each token only sees two experts, the\\nselected experts can be different at each timestep. As a result, each token has\\naccess to 47B parameters, but only uses 13B active parameters during inference.\\nMixtral was trained with a context size of 32k tokens and it outperforms or\\nmatches Llama 2 70B and GPT-3.5 across all evaluated benchmarks. In particular,\\nMixtral vastly outperforms Llama 2 70B on mathematics, code generation, and\\nmultilingual benchmarks. We also provide a model fine-tuned to follow\\ninstructions, Mixtral 8x7B - Instruct, that surpasses GPT-3.5 Turbo,\\nClaude-2.1, Gemini Pro, and Llama 2 70B - chat model on human benchmarks. Both\\nthe base and instruct models are released under the Apache 2.0 license.',\n",
       " 'source': 'http://arxiv.org/pdf/2401.04088',\n",
       " 'authors': 'Albert Q. Jiang, Alexandre Sablayrolles, Antoine Roux, Arthur Mensch, Blanche Savary, Chris Bamford, Devendra Singh Chaplot, Diego de las Casas, Emma Bou Hanna, Florian Bressand, Gianna Lengyel, Guillaume Bour, Guillaume Lample, Lélio Renard Lavaud, Lucile Saulnier, Marie-Anne Lachaux, Pierre Stock, Sandeep Subramanian, Sophia Yang, Szymon Antoniak, Teven Le Scao, Théophile Gervet, Thibaut Lavril, Thomas Wang, Timothée Lacroix, William El Sayed',\n",
       " 'categories': 'cs.LG, cs.CL',\n",
       " 'primary_category': 'cs.LG',\n",
       " 'published': '20240108',\n",
       " 'updated': '20240108'}"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Embedding and Upserting our data\n",
    "\n",
    "Below, we've written a useful upsertion script that handles rate limits nicely. We upsert in batches of 96, because this is the batch size limit for hosted models on Pinecone. This should take about a minute to upsert all of our data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "id": "vPb9liovzrc8"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Upserting records batch: 100%|██████████| 28/28 [00:26<00:00,  1.04it/s]\n"
     ]
    }
   ],
   "source": [
    "from tqdm import tqdm\n",
    "import backoff\n",
    "\n",
    "\n",
    "batch_size = 96\n",
    "dense_index = pc.Index(dense_index_name)\n",
    "\n",
    "\n",
    "@backoff.on_exception(backoff.expo, Exception, max_tries=8, max_time=80, on_backoff=lambda details: print(f\"Backoff: {details['tries']} of 8\"))\n",
    "def upsert_in_batches(dataset, index, batch_size):\n",
    "    for start in tqdm(range(0, len(dataset), batch_size), desc=\"Upserting records batch\"):\n",
    "        batch = dataset[start:start + batch_size]\n",
    "        index.upsert_records(namespace=\"arxiv\", records=batch)\n",
    "\n",
    "upsert_in_batches(dataset, dense_index, batch_size)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Upserting records batch: 100%|██████████| 28/28 [00:15<00:00,  1.82it/s]\n"
     ]
    }
   ],
   "source": [
    "sparse_index = pc.Index(sparse_index_name)\n",
    "\n",
    "upsert_in_batches(dataset, sparse_index, batch_size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2yiF91IbyGYo"
   },
   "source": [
    "Now we've added all of our papers and summaries and their embeddings to the index, we can work on the writing the cascading retrieval logic."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "VfP0TQVeG1hO"
   },
   "source": [
    "### Cascading Retrieval\n",
    "\n",
    "For many AI applications, dense or sparse search alone isn't enough to find relevant results. Cascading retrieval allows us to leverage the strengths of dense models and sparse models in order to further refine search results given a user query."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "kXXYoANbG13a"
   },
   "source": [
    "To implement cascading retrieval, we will need to conduct the following steps:\n",
    "\n",
    "1. Query: We query our sparse and dense indexes with a large top_k value\n",
    "2. Deduplicate: We combine and deduplicate results from the previous queries to achieve a preliminary result set\n",
    "3. Rerank: We pass this result set, and the query, to a Rerank endpoint hosted on Pinecone, returning our final set of documents\n",
    "\n",
    "The final set of documents can be considered the most relevant queries across dense and sparse search methods for the user.\n",
    "\n",
    "To learn more about exactly how reranking models can help improve relevance of search results, [check out our article here](https://www.pinecone.io/learn/refine-with-rerank/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "def query_pinecone(query, index, top_k=20):\n",
    "    # queries Pinecone given an index. \n",
    "    # The search endpoint embeds and queries the index with the model specified in index creation.\n",
    "    # Returns the top_k results ordered by relevance to the query\n",
    "\n",
    "    results = index.search(\n",
    "        namespace=\"arxiv\", \n",
    "        query={\n",
    "            \"inputs\": {\"text\": query}, \n",
    "            \"top_k\": top_k}\n",
    "        )\n",
    "    \n",
    "    return results\n",
    "\n",
    "def dedupe(sparse_results, dense_results):\n",
    "    # Deduplicates results from sparse and dense indexes\n",
    "\n",
    "\n",
    "    # Deduplicate by _id\n",
    "    deduped_hits = {hit['_id']: hit for hit in sparse_results['result']['hits'] + dense_results['result']['hits']}.values()\n",
    "    # Transform to format for reranking\n",
    "    result = [{'id': hit['_id'], \"title\": hit['fields']['title'], 'summary': hit['fields']['chunk_text']} for hit in deduped_hits]\n",
    "    return result\n",
    "\n",
    "\n",
    "def rerank(query, results, top_n=5):\n",
    "    # Calls a reranking model hosted on Pinecone, returning the top_n results ordered by relevance to the query\n",
    "    result = pc.inference.rerank(\n",
    "        # free-tier reranker\n",
    "        model=\"bge-reranker-v2-m3\",\n",
    "        query=query,\n",
    "        documents=results,\n",
    "        rank_fields=[\"summary\"],\n",
    "        top_n=10,\n",
    "        return_documents=True,\n",
    "        parameters={\n",
    "            \"truncate\": \"END\"\n",
    "        }\n",
    "    )\n",
    "    # rerank results\n",
    "    return result\n",
    "\n",
    "def cascading_retrieval(query, sparse_index, dense_index,top_k=10, top_n=5):\n",
    "    # Conducts a search over sparse and dense indexes, followed by deduplication and reranking\n",
    "    # Returns a list of top_n results ordered by relevance to the query\n",
    "\n",
    "    # query dense\n",
    "    dense_results = query_pinecone(query, dense_index, top_k)\n",
    "    # query sparse\n",
    "    sparse_results = query_pinecone(query, sparse_index, top_k)\n",
    "    # dedupe results\n",
    "    deduped_results = dedupe(sparse_results, dense_results)\n",
    "    # rerank results\n",
    "    reranked_results = rerank(query, deduped_results, top_n)\n",
    "    reranked_results = reranked_results.data\n",
    "\n",
    "    return reranked_results\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can take a look at the set of returned results here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2112.14397\n",
      "EvoMoE: An Evolutional Mixture-of-Experts Training Framework via Dense-To-Sparse Gate\n",
      "\n",
      "\n",
      "Mixture-of-experts (MoE) is becoming popular due to its success in improving\n",
      "the model quality, especially in Transformers. By routing tokens with a sparse\n",
      "gate to a few experts (i.e., a small pieces of the full model), MoE can easily\n",
      "increase the model parameters to a very large scale while keeping the\n",
      "computation cost in a constant level. Most existing works just initialize some\n",
      "random experts, set a fixed gating strategy (e.g., Top-k), and train the model\n",
      "from scratch in an ad-hoc way. We identify that these MoE models are suffering\n",
      "from the immature experts and unstable sparse gate, which are harmful to the\n",
      "convergence performance. In this paper, we propose an efficient end-to-end MoE\n",
      "training framework called EvoMoE. EvoMoE starts from training one single expert\n",
      "and gradually evolves into a large and sparse MoE structure. EvoMoE mainly\n",
      "contains two phases: the expert-diversify phase to train the base expert for a\n",
      "while and spawn multiple diverse experts from it, and the gate-sparsify phase\n",
      "to learn an adaptive sparse gate and activate a dynamic number of experts.\n",
      "EvoMoE naturally decouples the joint learning of both the experts and the\n",
      "sparse gate and focuses on learning the basic knowledge with a single expert at\n",
      "the early training stage. Then it diversifies the experts and continues to\n",
      "train the MoE with a novel Dense-to-Sparse gate (DTS-Gate). Specifically,\n",
      "instead of using a permanent sparse gate, DTS-Gate begins as a dense gate that\n",
      "routes tokens to all experts, then gradually and adaptively becomes sparser\n",
      "while routes to fewer experts. Evaluations are conducted on three popular\n",
      "models and tasks, including RoBERTa for masked language modeling task, GPT for\n",
      "language modeling task and Transformer for machine translation task. The\n",
      "results show that EvoMoE outperforms existing baselines, including Switch, BASE\n",
      "Layer, Hash Layer and StableMoE.\n",
      "\n",
      "\n",
      "2204.09636\n",
      "Residual Mixture of Experts\n",
      "\n",
      "\n",
      "Mixture of Experts (MoE) is able to scale up vision transformers effectively.\n",
      "However, it requires prohibiting computation resources to train a large MoE\n",
      "transformer. In this paper, we propose Residual Mixture of Experts (RMoE), an\n",
      "efficient training pipeline for MoE vision transformers on downstream tasks,\n",
      "such as segmentation and detection. RMoE achieves comparable results with the\n",
      "upper-bound MoE training, while only introducing minor additional training cost\n",
      "than the lower-bound non-MoE training pipelines. The efficiency is supported by\n",
      "our key observation: the weights of an MoE transformer can be factored into an\n",
      "input-independent core and an input-dependent residual. Compared with the\n",
      "weight core, the weight residual can be efficiently trained with much less\n",
      "computation resource, e.g., finetuning on the downstream data. We show that,\n",
      "compared with the current MoE training pipeline, we get comparable results\n",
      "while saving over 30% training cost. When compared with state-of-the-art non-\n",
      "MoE transformers, such as Swin-T / CvT-13 / Swin-L, we get +1.1 / 0.9 / 1.0\n",
      "mIoU gain on ADE20K segmentation and +1.4 / 1.6 / 0.6 AP gain on MS-COCO object\n",
      "detection task with less than 3% additional training cost.\n",
      "\n",
      "\n",
      "2202.08906\n",
      "ST-MoE: Designing Stable and Transferable Sparse Expert Models\n",
      "\n",
      "\n",
      "Scale has opened new frontiers in natural language processing -- but at a\n",
      "high cost. In response, Mixture-of-Experts (MoE) and Switch Transformers have\n",
      "been proposed as an energy efficient path to even larger and more capable\n",
      "language models. But advancing the state-of-the-art across a broad set of\n",
      "natural language tasks has been hindered by training instabilities and\n",
      "uncertain quality during fine-tuning. Our work focuses on these issues and acts\n",
      "as a design guide. We conclude by scaling a sparse model to 269B parameters,\n",
      "with a computational cost comparable to a 32B dense encoder-decoder Transformer\n",
      "(Stable and Transferable Mixture-of-Experts or ST-MoE-32B). For the first time,\n",
      "a sparse model achieves state-of-the-art performance in transfer learning,\n",
      "across a diverse set of tasks including reasoning (SuperGLUE, ARC Easy, ARC\n",
      "Challenge), summarization (XSum, CNN-DM), closed book question answering\n",
      "(WebQA, Natural Questions), and adversarially constructed tasks (Winogrande,\n",
      "ANLI R3).\n",
      "\n",
      "\n",
      "2101.03961\n",
      "Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity\n",
      "\n",
      "\n",
      "In deep learning, models typically reuse the same parameters for all inputs.\n",
      "Mixture of Experts (MoE) defies this and instead selects different parameters\n",
      "for each incoming example. The result is a sparsely-activated model -- with\n",
      "outrageous numbers of parameters -- but a constant computational cost. However,\n",
      "despite several notable successes of MoE, widespread adoption has been hindered\n",
      "by complexity, communication costs and training instability -- we address these\n",
      "with the Switch Transformer. We simplify the MoE routing algorithm and design\n",
      "intuitive improved models with reduced communication and computational costs.\n",
      "Our proposed training techniques help wrangle the instabilities and we show\n",
      "large sparse models may be trained, for the first time, with lower precision\n",
      "(bfloat16) formats. We design models based off T5-Base and T5-Large to obtain\n",
      "up to 7x increases in pre-training speed with the same computational resources.\n",
      "These improvements extend into multilingual settings where we measure gains\n",
      "over the mT5-Base version across all 101 languages. Finally, we advance the\n",
      "current scale of language models by pre-training up to trillion parameter\n",
      "models on the \"Colossal Clean Crawled Corpus\" and achieve a 4x speedup over the\n",
      "T5-XXL model.\n",
      "\n",
      "\n",
      "2209.01667\n",
      "A Review of Sparse Expert Models in Deep Learning\n",
      "\n",
      "\n",
      "Sparse expert models are a thirty-year old concept re-emerging as a popular\n",
      "architecture in deep learning. This class of architecture encompasses\n",
      "Mixture-of-Experts, Switch Transformers, Routing Networks, BASE layers, and\n",
      "others, all with the unifying idea that each example is acted on by a subset of\n",
      "the parameters. By doing so, the degree of sparsity decouples the parameter\n",
      "count from the compute per example allowing for extremely large, but efficient\n",
      "models. The resulting models have demonstrated significant improvements across\n",
      "diverse domains such as natural language processing, computer vision, and\n",
      "speech recognition. We review the concept of sparse expert models, provide a\n",
      "basic description of the common algorithms, contextualize the advances in the\n",
      "deep learning era, and conclude by highlighting areas for future work.\n",
      "\n",
      "\n",
      "2111.02358\n",
      "VLMo: Unified Vision-Language Pre-Training with Mixture-of-Modality-Experts\n",
      "\n",
      "\n",
      "We present a unified Vision-Language pretrained Model (VLMo) that jointly\n",
      "learns a dual encoder and a fusion encoder with a modular Transformer network.\n",
      "Specifically, we introduce Mixture-of-Modality-Experts (MoME) Transformer,\n",
      "where each block contains a pool of modality-specific experts and a shared\n",
      "self-attention layer. Because of the modeling flexibility of MoME, pretrained\n",
      "VLMo can be fine-tuned as a fusion encoder for vision-language classification\n",
      "tasks, or used as a dual encoder for efficient image-text retrieval. Moreover,\n",
      "we propose a stagewise pre-training strategy, which effectively leverages\n",
      "large-scale image-only and text-only data besides image-text pairs.\n",
      "Experimental results show that VLMo achieves state-of-the-art results on\n",
      "various vision-language tasks, including VQA, NLVR2 and image-text retrieval.\n",
      "The code and pretrained models are available at https://aka.ms/vlmo.\n",
      "\n",
      "\n",
      "2105.03036\n",
      "SpeechMoE: Scaling to Large Acoustic Models with Dynamic Routing Mixture of Experts\n",
      "\n",
      "\n",
      "Recently, Mixture of Experts (MoE) based Transformer has shown promising\n",
      "results in many domains. This is largely due to the following advantages of\n",
      "this architecture: firstly, MoE based Transformer can increase model capacity\n",
      "without computational cost increasing both at training and inference time.\n",
      "Besides, MoE based Transformer is a dynamic network which can adapt to the\n",
      "varying complexity of input instances in realworld applications. In this work,\n",
      "we explore the MoE based model for speech recognition, named SpeechMoE. To\n",
      "further control the sparsity of router activation and improve the diversity of\n",
      "gate values, we propose a sparsity L1 loss and a mean importance loss\n",
      "respectively. In addition, a new router architecture is used in SpeechMoE which\n",
      "can simultaneously utilize the information from a shared embedding network and\n",
      "the hierarchical representation of different MoE layers. Experimental results\n",
      "show that SpeechMoE can achieve lower character error rate (CER) with\n",
      "comparable computation cost than traditional static networks, providing\n",
      "7.0%-23.0% relative CER improvements on four evaluation datasets.\n",
      "\n",
      "\n",
      "2202.09368\n",
      "Mixture-of-Experts with Expert Choice Routing\n",
      "\n",
      "\n",
      "Sparsely-activated Mixture-of-experts (MoE) models allow the number of\n",
      "parameters to greatly increase while keeping the amount of computation for a\n",
      "given token or a given sample unchanged. However, a poor expert routing\n",
      "strategy (e.g. one resulting in load imbalance) can cause certain experts to be\n",
      "under-trained, leading to an expert being under or over-specialized. Prior work\n",
      "allocates a fixed number of experts to each token using a top-k function\n",
      "regardless of the relative importance of different tokens. To address this, we\n",
      "propose a heterogeneous mixture-of-experts employing an expert choice method.\n",
      "Instead of letting tokens select the top-k experts, we have experts selecting\n",
      "the top-k tokens. As a result, each token can be routed to a variable number of\n",
      "experts and each expert can have a fixed bucket size. We systematically study\n",
      "pre-training speedups using the same computational resources of the Switch\n",
      "Transformer top-1 and GShard top-2 gating of prior work and find that our\n",
      "method improves training convergence time by more than 2x. For the same\n",
      "computational cost, our method demonstrates higher performance in fine-tuning\n",
      "11 selected tasks in the GLUE and SuperGLUE benchmarks. For a smaller\n",
      "activation cost, our method outperforms the T5 dense model in 7 out of the 11\n",
      "tasks.\n",
      "\n",
      "\n",
      "2106.04426\n",
      "Hash Layers For Large Sparse Models\n",
      "\n",
      "\n",
      "We investigate the training of sparse layers that use different parameters\n",
      "for different inputs based on hashing in large Transformer models.\n",
      "Specifically, we modify the feedforward layer to hash to different sets of\n",
      "weights depending on the current token, over all tokens in the sequence. We\n",
      "show that this procedure either outperforms or is competitive with\n",
      "learning-to-route mixture-of-expert methods such as Switch Transformers and\n",
      "BASE Layers, while requiring no routing parameters or extra terms in the\n",
      "objective function such as a load balancing loss, and no sophisticated\n",
      "assignment algorithm. We study the performance of different hashing techniques,\n",
      "hash sizes and input features, and show that balanced and random hashes focused\n",
      "on the most local features work best, compared to either learning clusters or\n",
      "using longer-range context. We show our approach works well both on large\n",
      "language modeling and dialogue tasks, and on downstream fine-tuning tasks.\n",
      "\n",
      "\n",
      "2112.10684\n",
      "Efficient Large Scale Language Modeling with Mixtures of Experts\n",
      "\n",
      "\n",
      "Mixture of Experts layers (MoEs) enable efficient scaling of language models\n",
      "through conditional computation. This paper presents a detailed empirical study\n",
      "of how autoregressive MoE language models scale in comparison with dense models\n",
      "in a wide range of settings: in- and out-of-domain language modeling, zero- and\n",
      "few-shot priming, and full-shot fine-tuning. With the exception of fine-tuning,\n",
      "we find MoEs to be substantially more compute efficient. At more modest\n",
      "training budgets, MoEs can match the performance of dense models using $\\sim$4\n",
      "times less compute. This gap narrows at scale, but our largest MoE model (1.1T\n",
      "parameters) consistently outperforms a compute-equivalent dense model (6.7B\n",
      "parameters). Overall, this performance gap varies greatly across tasks and\n",
      "domains, suggesting that MoE and dense models generalize differently in ways\n",
      "that are worthy of future study. We make our code and models publicly available\n",
      "for research use.\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "query = \"What are Mixture of Expert models, compared to regular transformer models?\"\n",
    "\n",
    "results = cascading_retrieval(query, sparse_index, dense_index, top_k=10, top_n=5)\n",
    "\n",
    "\n",
    "for result in results:\n",
    "    print(result[\"document\"][\"id\"])\n",
    "    print(result[\"document\"][\"title\"])\n",
    "    print(\"\\n\")    \n",
    "    print(result[\"document\"][\"summary\"])\n",
    "    print(\"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A5dDWPGoIrd9"
   },
   "source": [
    "## Augmentation\n",
    "\n",
    "### Prompt Creation\n",
    "Next, we write some functions to retrieve these relevant contexts from Pinecone and incorporate them into a richer chat completion prompt. This is the \"augmentation\" part of retrieval augmented generation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "id": "92NmGGJ1TKQp"
   },
   "outputs": [],
   "source": [
    "def retrieval_augmented_prompt(query, sparse_index, dense_index, top_k=10, top_n=5):\n",
    "\n",
    "    # Get relevant contexts\n",
    "    query_results = cascading_retrieval(query, sparse_index, dense_index, top_k, top_n)\n",
    "\n",
    "    # Build our prompt with the retrieved contexts included\n",
    "    prompt_start = (\n",
    "        \"Answer the question based on the retrieved papers below.\\n\\n\"+\n",
    "        \"Retrieved Papers:\\n\"\n",
    "    )\n",
    "    prompt_end = (\n",
    "        f\"\\n\\nQuestion: {query}\\nAnswer:\"\n",
    "    )\n",
    "    context_separator = \"\\n\\n---\\n\\n\"\n",
    "\n",
    "    # Join contexts and trim to fit within limit\n",
    "    combined_contexts = []\n",
    "    total_length = 0\n",
    "    \n",
    "    for context in query_results:\n",
    "        formatted_paper = f\"Result Title: {context['document']['title']}\\n Result Summary: {context['document']['summary']}\"\n",
    "        combined_contexts.append(formatted_paper)\n",
    "    \n",
    "    return prompt_start + context_separator.join(combined_contexts) + prompt_end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 178
    },
    "id": "LwsZuxiTvU2d",
    "outputId": "33b465e7-360b-442c-8dbc-3359fd3ea50b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Answer the question based on the retrieved papers below.\n",
      "\n",
      "Retrieved Papers:\n",
      "Result Title: EvoMoE: An Evolutional Mixture-of-Experts Training Framework via Dense-To-Sparse Gate\n",
      " Result Summary: Mixture-of-experts (MoE) is becoming popular due to its success in improving\n",
      "the model quality, especially in Transformers. By routing tokens with a sparse\n",
      "gate to a few experts (i.e., a small pieces of the full model), MoE can easily\n",
      "increase the model parameters to a very large scale while keeping the\n",
      "computation cost in a constant level. Most existing works just initialize some\n",
      "random experts, set a fixed gating strategy (e.g., Top-k), and train the model\n",
      "from scratch in an ad-hoc way. We identify that these MoE models are suffering\n",
      "from the immature experts and unstable sparse gate, which are harmful to the\n",
      "convergence performance. In this paper, we propose an efficient end-to-end MoE\n",
      "training framework called EvoMoE. EvoMoE starts from training one single expert\n",
      "and gradually evolves into a large and sparse MoE structure. EvoMoE mainly\n",
      "contains two phases: the expert-diversify phase to train the base expert for a\n",
      "while and spawn multiple diverse experts from it, and the gate-sparsify phase\n",
      "to learn an adaptive sparse gate and activate a dynamic number of experts.\n",
      "EvoMoE naturally decouples the joint learning of both the experts and the\n",
      "sparse gate and focuses on learning the basic knowledge with a single expert at\n",
      "the early training stage. Then it diversifies the experts and continues to\n",
      "train the MoE with a novel Dense-to-Sparse gate (DTS-Gate). Specifically,\n",
      "instead of using a permanent sparse gate, DTS-Gate begins as a dense gate that\n",
      "routes tokens to all experts, then gradually and adaptively becomes sparser\n",
      "while routes to fewer experts. Evaluations are conducted on three popular\n",
      "models and tasks, including RoBERTa for masked language modeling task, GPT for\n",
      "language modeling task and Transformer for machine translation task. The\n",
      "results show that EvoMoE outperforms existing baselines, including Switch, BASE\n",
      "Layer, Hash Layer and StableMoE.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: Residual Mixture of Experts\n",
      " Result Summary: Mixture of Experts (MoE) is able to scale up vision transformers effectively.\n",
      "However, it requires prohibiting computation resources to train a large MoE\n",
      "transformer. In this paper, we propose Residual Mixture of Experts (RMoE), an\n",
      "efficient training pipeline for MoE vision transformers on downstream tasks,\n",
      "such as segmentation and detection. RMoE achieves comparable results with the\n",
      "upper-bound MoE training, while only introducing minor additional training cost\n",
      "than the lower-bound non-MoE training pipelines. The efficiency is supported by\n",
      "our key observation: the weights of an MoE transformer can be factored into an\n",
      "input-independent core and an input-dependent residual. Compared with the\n",
      "weight core, the weight residual can be efficiently trained with much less\n",
      "computation resource, e.g., finetuning on the downstream data. We show that,\n",
      "compared with the current MoE training pipeline, we get comparable results\n",
      "while saving over 30% training cost. When compared with state-of-the-art non-\n",
      "MoE transformers, such as Swin-T / CvT-13 / Swin-L, we get +1.1 / 0.9 / 1.0\n",
      "mIoU gain on ADE20K segmentation and +1.4 / 1.6 / 0.6 AP gain on MS-COCO object\n",
      "detection task with less than 3% additional training cost.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: ST-MoE: Designing Stable and Transferable Sparse Expert Models\n",
      " Result Summary: Scale has opened new frontiers in natural language processing -- but at a\n",
      "high cost. In response, Mixture-of-Experts (MoE) and Switch Transformers have\n",
      "been proposed as an energy efficient path to even larger and more capable\n",
      "language models. But advancing the state-of-the-art across a broad set of\n",
      "natural language tasks has been hindered by training instabilities and\n",
      "uncertain quality during fine-tuning. Our work focuses on these issues and acts\n",
      "as a design guide. We conclude by scaling a sparse model to 269B parameters,\n",
      "with a computational cost comparable to a 32B dense encoder-decoder Transformer\n",
      "(Stable and Transferable Mixture-of-Experts or ST-MoE-32B). For the first time,\n",
      "a sparse model achieves state-of-the-art performance in transfer learning,\n",
      "across a diverse set of tasks including reasoning (SuperGLUE, ARC Easy, ARC\n",
      "Challenge), summarization (XSum, CNN-DM), closed book question answering\n",
      "(WebQA, Natural Questions), and adversarially constructed tasks (Winogrande,\n",
      "ANLI R3).\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity\n",
      " Result Summary: In deep learning, models typically reuse the same parameters for all inputs.\n",
      "Mixture of Experts (MoE) defies this and instead selects different parameters\n",
      "for each incoming example. The result is a sparsely-activated model -- with\n",
      "outrageous numbers of parameters -- but a constant computational cost. However,\n",
      "despite several notable successes of MoE, widespread adoption has been hindered\n",
      "by complexity, communication costs and training instability -- we address these\n",
      "with the Switch Transformer. We simplify the MoE routing algorithm and design\n",
      "intuitive improved models with reduced communication and computational costs.\n",
      "Our proposed training techniques help wrangle the instabilities and we show\n",
      "large sparse models may be trained, for the first time, with lower precision\n",
      "(bfloat16) formats. We design models based off T5-Base and T5-Large to obtain\n",
      "up to 7x increases in pre-training speed with the same computational resources.\n",
      "These improvements extend into multilingual settings where we measure gains\n",
      "over the mT5-Base version across all 101 languages. Finally, we advance the\n",
      "current scale of language models by pre-training up to trillion parameter\n",
      "models on the \"Colossal Clean Crawled Corpus\" and achieve a 4x speedup over the\n",
      "T5-XXL model.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: A Review of Sparse Expert Models in Deep Learning\n",
      " Result Summary: Sparse expert models are a thirty-year old concept re-emerging as a popular\n",
      "architecture in deep learning. This class of architecture encompasses\n",
      "Mixture-of-Experts, Switch Transformers, Routing Networks, BASE layers, and\n",
      "others, all with the unifying idea that each example is acted on by a subset of\n",
      "the parameters. By doing so, the degree of sparsity decouples the parameter\n",
      "count from the compute per example allowing for extremely large, but efficient\n",
      "models. The resulting models have demonstrated significant improvements across\n",
      "diverse domains such as natural language processing, computer vision, and\n",
      "speech recognition. We review the concept of sparse expert models, provide a\n",
      "basic description of the common algorithms, contextualize the advances in the\n",
      "deep learning era, and conclude by highlighting areas for future work.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: VLMo: Unified Vision-Language Pre-Training with Mixture-of-Modality-Experts\n",
      " Result Summary: We present a unified Vision-Language pretrained Model (VLMo) that jointly\n",
      "learns a dual encoder and a fusion encoder with a modular Transformer network.\n",
      "Specifically, we introduce Mixture-of-Modality-Experts (MoME) Transformer,\n",
      "where each block contains a pool of modality-specific experts and a shared\n",
      "self-attention layer. Because of the modeling flexibility of MoME, pretrained\n",
      "VLMo can be fine-tuned as a fusion encoder for vision-language classification\n",
      "tasks, or used as a dual encoder for efficient image-text retrieval. Moreover,\n",
      "we propose a stagewise pre-training strategy, which effectively leverages\n",
      "large-scale image-only and text-only data besides image-text pairs.\n",
      "Experimental results show that VLMo achieves state-of-the-art results on\n",
      "various vision-language tasks, including VQA, NLVR2 and image-text retrieval.\n",
      "The code and pretrained models are available at https://aka.ms/vlmo.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: SpeechMoE: Scaling to Large Acoustic Models with Dynamic Routing Mixture of Experts\n",
      " Result Summary: Recently, Mixture of Experts (MoE) based Transformer has shown promising\n",
      "results in many domains. This is largely due to the following advantages of\n",
      "this architecture: firstly, MoE based Transformer can increase model capacity\n",
      "without computational cost increasing both at training and inference time.\n",
      "Besides, MoE based Transformer is a dynamic network which can adapt to the\n",
      "varying complexity of input instances in realworld applications. In this work,\n",
      "we explore the MoE based model for speech recognition, named SpeechMoE. To\n",
      "further control the sparsity of router activation and improve the diversity of\n",
      "gate values, we propose a sparsity L1 loss and a mean importance loss\n",
      "respectively. In addition, a new router architecture is used in SpeechMoE which\n",
      "can simultaneously utilize the information from a shared embedding network and\n",
      "the hierarchical representation of different MoE layers. Experimental results\n",
      "show that SpeechMoE can achieve lower character error rate (CER) with\n",
      "comparable computation cost than traditional static networks, providing\n",
      "7.0%-23.0% relative CER improvements on four evaluation datasets.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: Mixture-of-Experts with Expert Choice Routing\n",
      " Result Summary: Sparsely-activated Mixture-of-experts (MoE) models allow the number of\n",
      "parameters to greatly increase while keeping the amount of computation for a\n",
      "given token or a given sample unchanged. However, a poor expert routing\n",
      "strategy (e.g. one resulting in load imbalance) can cause certain experts to be\n",
      "under-trained, leading to an expert being under or over-specialized. Prior work\n",
      "allocates a fixed number of experts to each token using a top-k function\n",
      "regardless of the relative importance of different tokens. To address this, we\n",
      "propose a heterogeneous mixture-of-experts employing an expert choice method.\n",
      "Instead of letting tokens select the top-k experts, we have experts selecting\n",
      "the top-k tokens. As a result, each token can be routed to a variable number of\n",
      "experts and each expert can have a fixed bucket size. We systematically study\n",
      "pre-training speedups using the same computational resources of the Switch\n",
      "Transformer top-1 and GShard top-2 gating of prior work and find that our\n",
      "method improves training convergence time by more than 2x. For the same\n",
      "computational cost, our method demonstrates higher performance in fine-tuning\n",
      "11 selected tasks in the GLUE and SuperGLUE benchmarks. For a smaller\n",
      "activation cost, our method outperforms the T5 dense model in 7 out of the 11\n",
      "tasks.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: Hash Layers For Large Sparse Models\n",
      " Result Summary: We investigate the training of sparse layers that use different parameters\n",
      "for different inputs based on hashing in large Transformer models.\n",
      "Specifically, we modify the feedforward layer to hash to different sets of\n",
      "weights depending on the current token, over all tokens in the sequence. We\n",
      "show that this procedure either outperforms or is competitive with\n",
      "learning-to-route mixture-of-expert methods such as Switch Transformers and\n",
      "BASE Layers, while requiring no routing parameters or extra terms in the\n",
      "objective function such as a load balancing loss, and no sophisticated\n",
      "assignment algorithm. We study the performance of different hashing techniques,\n",
      "hash sizes and input features, and show that balanced and random hashes focused\n",
      "on the most local features work best, compared to either learning clusters or\n",
      "using longer-range context. We show our approach works well both on large\n",
      "language modeling and dialogue tasks, and on downstream fine-tuning tasks.\n",
      "\n",
      "---\n",
      "\n",
      "Result Title: Efficient Large Scale Language Modeling with Mixtures of Experts\n",
      " Result Summary: Mixture of Experts layers (MoEs) enable efficient scaling of language models\n",
      "through conditional computation. This paper presents a detailed empirical study\n",
      "of how autoregressive MoE language models scale in comparison with dense models\n",
      "in a wide range of settings: in- and out-of-domain language modeling, zero- and\n",
      "few-shot priming, and full-shot fine-tuning. With the exception of fine-tuning,\n",
      "we find MoEs to be substantially more compute efficient. At more modest\n",
      "training budgets, MoEs can match the performance of dense models using $\\sim$4\n",
      "times less compute. This gap narrows at scale, but our largest MoE model (1.1T\n",
      "parameters) consistently outperforms a compute-equivalent dense model (6.7B\n",
      "parameters). Overall, this performance gap varies greatly across tasks and\n",
      "domains, suggesting that MoE and dense models generalize differently in ways\n",
      "that are worthy of future study. We make our code and models publicly available\n",
      "for research use.\n",
      "\n",
      "Question: What are Mixture of Expert models, compared to regular transformer models?\n",
      "Answer:\n"
     ]
    }
   ],
   "source": [
    "prompt_with_context = retrieval_augmented_prompt(query, sparse_index, dense_index, top_k=10, top_n=5)\n",
    "print(prompt_with_context)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Generation: Calling OpenAI to create a response\n",
    "\n",
    "Now that we are building a rich prompt with context from our index, we are ready to get chat completions from OpenAI."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 53
    },
    "id": "ioDVGF7lkDQL",
    "outputId": "304ece44-0205-41b5-8c98-e5e5d47ee21f"
   },
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "def chat_completion(prompt):\n",
    "\n",
    "    # Instantiate the OpenAI client\n",
    "    client = OpenAI(api_key=OPENAI_API_KEY)\n",
    "    \n",
    "    # Instructions\n",
    "    sys_prompt = \"You are a helpful assistant that always answers questions.\"\n",
    "    res = client.chat.completions.create(\n",
    "        model='gpt-4o-mini',\n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": sys_prompt},\n",
    "            {\"role\": \"user\", \"content\": prompt}\n",
    "        ],\n",
    "        temperature=0\n",
    "    )\n",
    "    return res.choices[0].message.content.strip()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Final workflow\n",
    "\n",
    "To implement RAG, we simply create our prompt using cascading retrieval results, and pass it to an OpenAI LLM call!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "def rag(query):\n",
    "    # Retrieval relevant results, format into a prompt, and pass to OpenAI\n",
    "    \n",
    "    prompt = retrieval_augmented_prompt(query, sparse_index, dense_index, top_k=20, top_n=5)\n",
    "    return chat_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mixture of Experts (MoE) models are a specialized architecture within the realm of deep learning, particularly designed to enhance the efficiency and scalability of neural networks, especially in comparison to regular transformer models. Here are the key differences:\n",
      "\n",
      "1. **Parameter Utilization**: MoE models utilize a sparse activation mechanism, where only a subset of the model's parameters (experts) is activated for each input. This allows MoE models to have a significantly larger number of parameters while maintaining a constant computational cost per input. In contrast, regular transformer models typically use the same parameters for all inputs, leading to a direct correlation between the number of parameters and the computational cost.\n",
      "\n",
      "2. **Dynamic Routing**: In MoE models, tokens are routed to different experts based on a gating mechanism, which can adaptively select which experts to activate for a given input. This dynamic routing allows MoE models to handle varying complexities of input data more effectively. Regular transformers do not have this dynamic routing; they process all inputs through the same set of parameters.\n",
      "\n",
      "3. **Training Efficiency**: MoE models can achieve significant training cost reductions compared to dense models of equivalent quality. For instance, some studies have shown that MoE models can save up to 5x in training costs for certain tasks. Regular transformers do not benefit from this level of efficiency due to their dense parameter usage.\n",
      "\n",
      "4. **Scalability**: MoE models are designed to scale to very large sizes (e.g., trillion-parameter models) while keeping computational costs manageable. This scalability is a significant advantage over regular transformers, which may face limitations in terms of hardware resources and training time as they grow larger.\n",
      "\n",
      "5. **Performance on Diverse Tasks**: MoE models have demonstrated state-of-the-art performance across various tasks, including natural language processing, computer vision, and speech recognition, by leveraging their ability to activate different experts for different inputs. Regular transformers may not achieve the same level of performance due to their fixed parameter usage.\n",
      "\n",
      "6. **Training Stability**: While MoE models offer advantages in terms of efficiency and scalability, they can also face challenges such as training instabilities and under-training of certain experts. Recent advancements in MoE architectures aim to address these issues, whereas regular transformers typically do not encounter such complexities.\n",
      "\n",
      "In summary, Mixture of Experts models provide a flexible, efficient, and scalable alternative to regular transformer models by utilizing a sparse activation mechanism, dynamic routing, and the ability to handle larger parameter counts without a corresponding increase in computational cost.\n"
     ]
    }
   ],
   "source": [
    "query = \"What are Mixture of Expert models, compared to regular transformer models?\"\n",
    "\n",
    "\n",
    "answer = rag(query)\n",
    "print(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Demo cleanup"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "sjOBIQ5rFeLZ"
   },
   "source": [
    "Once we're done with the index we can delete our index to save resources:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "PpJp-xExFeLa"
   },
   "outputs": [],
   "source": [
    "pc.delete_index(name=dense_index_name)\n",
    "pc.delete_index(name=sparse_index_name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2kNh44bEFeLe"
   },
   "source": [
    "---"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "pinecone-examples",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
